package tpoo.client.ui.editors;

import static tpoo.common.services.utils.ServiceConstants.USER_SERVICE;

import java.util.Observable;
import java.util.Observer;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorPart;

import tpoo.common.dto.model.ReceivedMessage;
import tpoo.common.dto.model.users.UserDTO;
import tpoo.common.services.UserService;
import tpoo.common.services.exceptions.ServiceException;
import tpoo.common.services.utils.ServiceAdmin;
import tpoo.common.utils.UserSession;

public class ChatEditor extends EditorPart implements Observer {

	public static String ID = "tpoo-client.chatEditor";

	private Text transcript;
	private Text entry;

	public ChatEditor() {
		// TODO Auto-generated constructor stub
		UserSession.getInstance().getUser().addObserver(this);
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		// TODO Auto-generated method stub

	}

	@Override
	public void doSaveAs() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		setSite(site);
		setInput(input);
		setPartName(getUser());
	}

	@Override
	public boolean isDirty() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {
		Composite top = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		top.setLayout(layout);

		// TODO poner scrollbars al transcript

		transcript = new Text(top, SWT.BORDER | SWT.MULTI | SWT.WRAP);
		transcript.setLayoutData(new GridData(GridData.FILL, GridData.FILL,
				true, true));
		transcript.setEditable(false);
		transcript.setBackground(transcript.getDisplay().getSystemColor(
				SWT.COLOR_INFO_BACKGROUND));
		transcript.setForeground(transcript.getDisplay().getSystemColor(
				SWT.COLOR_INFO_FOREGROUND));

		entry = new Text(top, SWT.BORDER | SWT.WRAP);
		GridData gridData = new GridData(GridData.FILL, GridData.FILL, true,
				false);

		gridData.heightHint = entry.getLineHeight() * 2;
		entry.setLayoutData(gridData);
		entry.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent event) {
				if (event.character == SWT.CR) {
					sendMessage();
					// ignore the CR and don't add to text control
					event.doit = false;
				}
			}
		});
	}

	@Override
	public void setFocus() {
		if (entry != null && !entry.isDisposed()) {
			entry.setFocus();
		}
	}

	private String getUser() {
		return ((ChatEditorInput) getEditorInput()).getName();
	}

	private String renderMessage(String from, String body) {
		if (from == null)
			return body;
		int j = from.indexOf('@');
		if (j > 0)
			from = from.substring(0, j);
		return "<" + from + "> " + body;
	}

	private void scrollToEnd() {
		int n = transcript.getCharCount();
		transcript.setSelection(n, n);
		transcript.showSelection();
	}

	private void sendMessage() {
		String body = entry.getText();
		if (body.length() == 0)
			return;

		UserDTO contact = (UserDTO) UserSession.getInstance().getUser()
				.getContact(getUser());
		UserService us;
		try {
			us = (UserService) ServiceAdmin.getService(USER_SERVICE);
			UserDTO udto = UserSession.getInstance().getUser();
			us.sendMessage(udto, contact, body);
			transcript.append(renderMessage(UserSession.getInstance().getUser()
					.getUsername(), body));
			transcript.append("\n");
			scrollToEnd();
			entry.setText("");
		} catch (ServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void update(Observable o, Object arg) {
		if (arg instanceof ReceivedMessage) {
			final ReceivedMessage rm = (ReceivedMessage) arg;
			if (rm.getUserID().equals(this.getUser())) {
				PlatformUI.getWorkbench().getDisplay().asyncExec(
						new Runnable() {
							public void run() {
								transcript.append(renderMessage(rm.getUserID()
										.toString(), rm.getMessage()));
								transcript.append("\n");
								scrollToEnd();
							}
						});
			}
		}
	}
}
